<?php

 /**
  * @package JooS
  * @subpackage PHPackager
  */

  require_once "JooS/PHPackager/DOM/Element.php";

  abstract class JooS_PHPackager_DOM_Element_Relations_Abstract extends JooS_PHPackager_DOM_Element {
    /**
     * @var string
     */
    private $_compiledCode = null;

    /**
     * @return JooS_Syntax_PHPackager_Relations_Abstract
     */
    abstract function getSyntaxLanguage();

    /**
     * @return string
     */
    private function getFunctionName() {
      return "_init" . ucfirst(strtolower($this->getNode()->tagName));
    }

    /**
     * @return string
     */
    public function getCompiledCode() {
      return "return " . $this->_compiledCode . ";";
    }

    /**
     * @return JooS_PHPackager_DOM_Element_Relations_Abstract
     */
    public function make() {
      $this->_compiledCode = JooS_Syntax_Compiler::newInstance( $this->getSyntaxLanguage() )
        ->compile( $this->getNode()->textContent );

      if ($this->_compiledCode === false)
        self::throwException("Parse Error in '" . $this->getFunctionName() . "' tag");

      return $this;
    }

    /**
     * @return JooS_PHPackager_DOM_Element_Relations_Abstract
     */
    public function install() {
      require_once "JooS/Event.php";
      require_once "JooS/CodeGenerator/Method.php";
      require_once "JooS/PHPackager/DOM/Element/Package.php";

      $newMethod = JooS_CodeGenerator_Method::newInstance($this->getFunctionName())
        ->setVisibility(JooS_CodeGenerator_Method::VISIBILITY_PROTECTED)
        ->setBody( $this->getCompiledCode() );
      
      JooS_Event::newInstance(JooS_PHPackager_DOM_Element_Package::EVENT_NEW_METHOD)->notify($newMethod);

      return $this;
    }
  }
